package com.clp.protocol.core.common.frame;

import com.clp.protocol.core.exception.InvalidFrameClipException;
import com.clp.protocol.core.utils.ByteUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;

/**
 * 帧片段：一个帧片段由一些子的帧片段组成，最终的帧片段为原子的帧片段
 * @param <FC>
 */
public interface FrameClip<FC extends FrameClip<FC>> {
    /**
     * 是否是有效的帧片段
     * @return
     */
    boolean isValid();

    /**
     * 检查帧片段是否有效
     */
    default void checkValid() {
        if (!isValid()) throw new InvalidFrameClipException(this);
    }

    /**
     * 写入 {@link ByteBuf}
     */
    void writeTo(ByteBuf buf);

    /**
     * 转换为 十六进制 字符串数组，一个字节对应一个 十六进制字符串
     *
     * @return 如 {"00", "01", "02", "0A", "1B", ...}
     */
    default String[] toHexStrArray() {
        byte[] byteArray = this.toByteArray();
        int len = byteArray.length;
        String[] hexStrArray = new String[len];
        for (int i = 0; i < len; i++) {
            hexStrArray[i] = ByteUtil.byteToHexStr(byteArray[i], true);
        }
        return hexStrArray;
    }

    /**
     * 转换为 十六进制 字符串
     * @return 如 "[ 00 01 02 0A 1B ... ]"
     */
    default String toHexString() {
        String[] str = toHexStrArray();
        StringBuilder sb = new StringBuilder("[ ");
        for (int i = 0; i < str.length; i++) {
            if (i == 0) {
                sb.append(str[i]);
            } else {
                sb.append(" ").append(str[i]);
                if (i % 50 == 0) {
                    sb.append("\n");
                }
            }
        }
        return sb.append(" ]").toString();
    }

    /**
     * 转换为字节数组
     *
     * @return 如 {0x00, 0x01, 0x02, 0x0A, 0x1B, ...}
     */
    default byte[] toByteArray() {
        ByteBuf buf = ByteBufAllocator.DEFAULT.heapBuffer();
        this.writeTo(buf);
        byte[] retBytes = new byte[buf.readableBytes()]; buf.readBytes(retBytes);
        buf.release();
        return retBytes;
    }
}
